vncpid = None
+def daemonize(prog, args):
+ """Runs a program as a daemon with the list of arguments. Returns the PID
+ of the daemonized program, or returns 0 on error.
+ """
+ r, w = os.pipe()
+ pid = os.fork()
+
+ if pid == 0:
+ os.close(r)
+ w = os.fdopen(w, 'w')
+ os.setsid()
+ try:
+ pid2 = os.fork()
+ except:
+ pid2 = None
+ if pid2 == 0:
+ os.chdir("/")
+ for fd in range(0, 256):
+ try:
+ os.close(fd)
+ except:
+ pass
+ os.open("/dev/null", os.O_RDWR)
+ os.dup2(0, 1)
+ os.dup2(0, 2)
+ os.execvp(prog, args)
+ os._exit(1)
+ else:
+ w.write(str(pid2 or 0))
+ w.close()
+ os._exit(0)
+
+ os.close(w)
+ r = os.fdopen(r)
+ daemon_pid = int(r.read())
+ r.close()
+ os.waitpid(pid, 0)
+ return daemon_pid
+
def spawn_vnc(display):
+ """Spawns a vncviewer that listens on the specified display. On success,
+ returns the port that the vncviewer is listening on and sets the global
+ vncpid. On failure, returns 0. Note that vncviewer is daemonized.
+ """
vncargs = (["vncviewer", "-log", "*:stdout:0",
"-listen", "%d" % (VNC_BASE_PORT + display) ])
- global vncpid
- vncpid = os.spawnvp(os.P_NOWAIT, "vncviewer", vncargs)
-
+ global vncpid
+ vncpid = daemonize("vncviewer", vncargs)
+ if vncpid == 0:
+ return 0
return VNC_BASE_PORT + display
-
+
def preprocess_vnc(vals):
"""If vnc was specified, spawn a vncviewer in listen mode
and pass its address to the domain on the kernel command line.